package com.aepryus.loom;

import java.util.*;
import java.beans.*;
import java.lang.reflect.*;
import com.aepryus.xml.*;

public class DomainMapper {
	private static Map<String,DomainMapper> mappers = new HashMap<String,DomainMapper>();

	public static Map toMap (Domain domain) {
		DomainMapper mapper = mappers.get(domain.getDomain());
		if (mapper == null)
			mapper = new DomainMapper(domain);
		return mapper.getMap(domain);
	}

	private Map<String,PropertyDescriptor> properties;

	private DomainMapper (Domain domain) {
		initialize(domain.getClass());
		mappers.put(domain.getDomain(),this);
	}

	private void initialize (Class bean) {
		try {
			BeanInfo info = Introspector.getBeanInfo(bean);
			properties = new HashMap<String,PropertyDescriptor>();
			for (int i=0;i<info.getPropertyDescriptors().length;i++) {
				PropertyDescriptor pd = info.getPropertyDescriptors()[i];
				if (pd.getReadMethod() != null && pd.getWriteMethod() != null)
					properties.put(pd.getName(),pd);
			}
		} catch (IntrospectionException e) {
			throw new RuntimeException(e.getMessage());
		}
	}

	public Map getMap (Domain domain) {
		try {
			Map<String,Object> map = new HashMap<String,Object>();
			for (String name : properties.keySet()) {
				Method read = properties.get(name).getReadMethod();
				Object result = read.invoke(domain,new Object[]{});
				if (result != null)
					map.put(name, result);
			}
			if (domain.isNew())
				map.put(domain.getDomain()+"ID",(long)0);
			return map;
		} catch (InvocationTargetException e) {
			throw new XMLException(e);
		} catch (IllegalAccessException e) {
			throw new XMLException(e);
		}
	}
}

